/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY. 
 * See the GNU General Public License for more details.
 * 
 * Copyright (C) 2011 CellObject.net
 */
package net.cellobject.javacodeformatter.editor;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * A group of related property entries in a {@link PropertyFile} with a comment preceding the group indicating the name. The
 * category can extract its name and entries from a reader object.
 */
public class PropertyCategory extends PropertyElement {
	private String name;

	private final List<PropertyEntry> entries;

	public PropertyCategory(final PropertyFile parent, final LineNumberReader reader) throws IOException {
		super(parent);
		// Determine the category name from comments.
		while (true) {
			reader.mark(1);
			final int ch = reader.read();
			if (ch == -1) {
				break;
			}
			reader.reset();
			if (ch != '#') {
				break;
			}
			String line = reader.readLine();
			if (name == null) {
				line = line.replace('#', ' ').trim();
				if (line.length() > 0) {
					name = line;
				}
			}
		}
		if (name == null) {
			name = "";
		}
		// Determine the properties in this category.
		entries = new ArrayList<PropertyEntry>();
		while (true) {
			reader.mark(1);
			final int ch = reader.read();
			if (ch == -1) {
				break;
			}
			reader.reset();
			if (ch == '#') {
				break;
			}
			final String line = reader.readLine();
			final int index = line.indexOf('=');
			if (index != -1) {
				final String key = line.substring(0, index).trim();
				final String value = line.substring(index + 1).trim();
				entries.add(new PropertyEntry(this, key, value));
			}
		}
	}

	public String getName() {
		return name;
	}

	public Collection<PropertyEntry> getEntries() {
		return entries;
	}

	@Override
	public PropertyElement[] getChildren() {
		return entries.toArray(new PropertyElement[entries.size()]);
	}

	public void setName(final String text) {
		if (name.equals(text)) {
			return;
		}
		name = text;
		((PropertyFile)getParent()).nameChanged(this);
	}

	public void addEntry(final PropertyEntry entry) {
		addEntry(entries.size(), entry);
	}

	public void addEntry(final int index, final PropertyEntry entry) {
		if (!entries.contains(entry)) {
			entries.add(index, entry);
			((PropertyFile)getParent()).entryAdded(this, entry);
		}
	}

	public void removeEntry(final PropertyEntry entry) {
		if (entries.remove(entry)) {
			((PropertyFile)getParent()).entryRemoved(this, entry);
		}
	}

	@Override
	public void removeFromParent() {
		((PropertyFile)getParent()).removeCategory(this);
	}

	public void keyChanged(final PropertyEntry entry) {
		((PropertyFile)getParent()).keyChanged(this, entry);
	}

	public void valueChanged(final PropertyEntry entry) {
		((PropertyFile)getParent()).valueChanged(this, entry);
	}

	public void appendText(final PrintWriter writer) {
		if (name.length() > 0) {
			writer.print("# ");
			writer.println(name);
		}
		final Iterator<PropertyEntry> iter = entries.iterator();
		while (iter.hasNext()) {
			iter.next().appendText(writer);
		}
	}
}
